﻿using Sustainalytics.DataLayer;
using Sustainalytics.Entities;
using System;
using System.Collections.Generic;
using System.Linq;
using Sustainalytics.ScreeningTool.BL.Exceptions;
using Sustainalytics.Utils;
using Sustainalytics.ClientDW.DataAccessLayer;
using Sustainalytics.ScreeningTool.BL.Model;
using Sustainalytics.DataLayer.Shared;
using Sustainalytics.Replication.Publisher;
using Newtonsoft.Json;
using Sustainalytics.ScreeningTool.BL.Serilog;

namespace Sustainalytics.ScreeningTool.BL
{
    public class FilterManager : Sustainalytics.ScreeningTool.BL.IFilterManager
    {
        private IAccountsRepository _accountsRepository;
        private ICompanyScreeningRepository _companyScreeningRepository;
        private IFiltersRepository _filtersRepository;
        private IFilterCriteriaRepository _filterCriteriaRepository;
        private IRepositoryCollection<UserFilterSettings> _userFilterSettingsRepository;
        private IClientDwRepository _clientDWRepository;
        private ServiceBusPublisher _serviceBusPublisher;

        public static FilterManager CreateFilterManager(
            string clientPlatformConnectionString, 
            string clientDWConnectionString, 
            ServiceBusPublisher serviceBusPublisher)
        {
            var accountsRepository = AccountsRepository.GetAccountsRepository(clientPlatformConnectionString);
            var companyScreeningRepository = CompanyScreeningRepository.GetCompanyScreeningRepository(clientPlatformConnectionString);
            var filtersRepository = new FiltersRepository(clientPlatformConnectionString);
            var filterCriteriaRepository = new FilterCriteriaRepository(clientPlatformConnectionString);
            var userFilterSettingsRepository = new RepositoryCollection<UserFilterSettings>(clientPlatformConnectionString);
            var clientDWRepository = ClientDwRepository.GetInstance(clientDWConnectionString);

            return new FilterManager(
                accountsRepository, 
                companyScreeningRepository, 
                filtersRepository, 
                filterCriteriaRepository, 
                userFilterSettingsRepository, 
                clientDWRepository, 
                serviceBusPublisher);
        }

        public FilterManager(
            IAccountsRepository accountsRepository, 
            ICompanyScreeningRepository companyScreeningRepository, 
            IFiltersRepository filtersRepository, 
            IFilterCriteriaRepository filterCriteriaRepository, 
            IRepositoryCollection<UserFilterSettings> userFilterSettingsRepository,
            IClientDwRepository clientDWRepository,
            ServiceBusPublisher serviceBusPublisher)
        {
            _accountsRepository = accountsRepository;
            _companyScreeningRepository = companyScreeningRepository;
            _filtersRepository = filtersRepository;
            _filterCriteriaRepository = filterCriteriaRepository;
            _userFilterSettingsRepository = userFilterSettingsRepository;
            _clientDWRepository = clientDWRepository;
            _serviceBusPublisher = serviceBusPublisher;
        }

        public List<Filter> GetAccountFilters(Guid accountId)
        {
            var result = _filtersRepository.GetAccountFilters(accountId);
            return result;
        }

        /// <summary>
        /// Gets owned custom filters  + Shared filters within account + standard filters
        /// </summary>
        public List<Filter> GetUserFilters(string userName, TargetType targetType)
        {
            if (userName == null)
            {
                throw new ArgumentNullException("userName");
            }

            User user = _accountsRepository.GetUserByUsername(userName);
            if (user == null)
            {
                throw new UnknownUserException(userName);
            }

            IEnumerable<Filter> filters = null;
            
            //gets standard filters
            var standardFilters = _filtersRepository.GetStandardFilters(targetType);
            filters = standardFilters;

            if (user.AccountId.HasValue)
            {
                //gets shared filters within account
                var accountFilters = _filtersRepository.GetFiltersByAccountId(user.Id, user.AccountId.Value, targetType, FilterType.Shared);
                if (accountFilters != null)
                {
                    filters = filters.Union(accountFilters).ToList();
                }
            }

            //get user owned filters
            var ownedFilters = _filtersRepository.GetFiltersByOwner(new List<Guid>() {user.Id}, user.AccountId, targetType);
            if (ownedFilters != null)
            {
                filters = filters.Union(ownedFilters).ToList();
            }

            #region custom ordering

            //get filter order from UserFilterSettings
            List<Guid> filterOrder = new List<Guid>();

            var allStandardAndFavFiltersIds = filters.Where(x => x.Type == FilterType.Standard || x.IsFavorite).OrderByDescending(x => x.TargetType).ThenByDescending(x=>x.CreatedAt).Select(x => x.Id);
            var standardAndFavFilterOrder = GetAreaFilterOrder(allStandardAndFavFiltersIds, user, targetType, ScreenRegion.SystemAndFavFilters);
            filterOrder.AddRange(standardAndFavFilterOrder);

            var allOtherFiltersIds = filters.Where(x => x.Type != FilterType.Standard && !x.IsFavorite).OrderByDescending(x => x.TargetType).ThenByDescending(x=>x.CreatedAt).Select(x => x.Id);
            var otherFilterOrder = GetAreaFilterOrder(allOtherFiltersIds, user, targetType, ScreenRegion.OtherFilters);
            filterOrder.AddRange(otherFilterOrder);

            //////////////////////////////////

            if (filterOrder.Any())
            {
                List<Filter> orderedResult = new List<Filter>();

                filterOrder.ForEach(x =>
                {

                    var foundFilter = filters.Where(o => o.Id == x).SingleOrDefault();
                    if (foundFilter != null)
                    {
                        orderedResult.Add(foundFilter);
                    }
                });
                return orderedResult;
            }

            #endregion

            return filters.ToList();
        }


        public List<Guid> GetAreaFilterOrder(IEnumerable<Guid> filterIds , User user, TargetType targetType, ScreenRegion screenRegion)
        {
            List<Guid> result = new List<Guid>();
            var regionFiltersOrderByTarget = _userFilterSettingsRepository.ReadAllWhere(x => x.UserId == user.Id && x.AccountId == user.AccountId && x.TargetType == targetType && x.ScreenRegion == screenRegion);

            if (regionFiltersOrderByTarget.Any())
            {
                var foundResult = regionFiltersOrderByTarget.FirstOrDefault();
                
                var missingFilters = filterIds.Where(x => !foundResult.FilterIds.Contains(x));
                if (missingFilters.Any())
                {
                    foundResult.FilterIds.InsertRange(0, missingFilters);
                    //save to UserFilterSettings
                    _userFilterSettingsRepository.CreateOrUpdate(foundResult);
                    _serviceBusPublisher.SendMessage(JsonConvert.SerializeObject(foundResult), ReplicationUtils.EntityType.UserFilterSettings, ReplicationUtils.Operation.CreateOrUpdate);
                }

                result.AddRange(foundResult.FilterIds);
            }
            else
            {
                SaveUserCustomFilterOrder(user.Id, user.AccountId, targetType, screenRegion, filterIds.ToList());
                result.AddRange(filterIds);
            }
            return result;
        }

        /// <summary>
        /// load the criteria of a filter
        /// </summary>
        /// <param name="userName">the userName for the user in whose filter the criteria are loaded</param>
        public Filter LoadFilter(Guid filterId, string userName)
        {
            User currentUser = _accountsRepository.GetUserByUsername(userName);
            if (currentUser == null)
                throw new UnknownUserException(userName);

            var filter = _filtersRepository.GetFilterById(filterId);

            return filter;
        }

        public void EditFilter(string userName, Filter filter)
        {
            User currentUser = _accountsRepository.GetUserByUsername(userName);
            if (currentUser == null)
                throw new UnknownUserException(userName);

            var originalFilter = _filtersRepository.GetFilterById(filter.Id);

            if (string.IsNullOrEmpty(filter.Name))
                throw new FilterValidationException { InternalCode = FilterValidationErrorCodes.NullOrEmptyName };

            if (originalFilter.Name != filter.Name)
            {
                if (!ValidateFilterPrivateName(filter.Name, currentUser, filter.TargetType))
                    throw new FilterValidationException { InternalCode = FilterValidationErrorCodes.DuplicatePrivateName };

                if (!ValidateFilterSharedName(filter.Name, filter.TargetType, filter.Type, currentUser))
                    throw new FilterValidationException { InternalCode = FilterValidationErrorCodes.DuplicateSharedName };
            }

            _serviceBusPublisher.SendMessage(JsonConvert.SerializeObject(filter), ReplicationUtils.EntityType.Filter, ReplicationUtils.Operation.Update);
            _filtersRepository.SaveFilter(filter);
        }

        public Filter SaveFilter(string userName, FilterAddEditDto filterDto)
        {
            Guid? sourceFilterId = null;
            bool isFavChanged = false;
            bool isNameChanged = true;
            bool isSharedChanged = false;

            User currentUser = _accountsRepository.GetUserByUsername(userName);
            if (currentUser == null)
                throw new UnknownUserException(userName);

            Filter filter = null;

            if (filterDto.Id == null)
            {
                filter = new Filter
                {
                    Id = Guid.NewGuid(),
                    Name = filterDto.Name,
                    Type = FilterType.Private,
                    OwnerUserId = currentUser.Id,
                    AccountId = currentUser.AccountId.Value,
                    CreatedAt = DateTime.Now.ToUniversalTime(),
                    LastSaved = DateTime.Now.ToUniversalTime(),
                    IsFavorite = false,
                    Status = FilterStatus.Active,
                    TargetType = filterDto.TargetType,
                    ExportType = filterDto.ExportType
                };
            }
            else
            {
                filter = _filtersRepository.GetFilterById(filterDto.Id.Value);

                if (filterDto.IsSourceForClone)
                {
                    if (filterDto.Type == FilterType.Standard)
                    {
                        filterDto.Type = FilterType.Private;
                    }

                    sourceFilterId = filter.Id;
                    filter.OwnerUserId = currentUser.Id;
                    filter.AccountId = currentUser.AccountId.Value;
                    filter.Id = Guid.NewGuid();
                }

                if (filter.IsFavorite != filterDto.IsFavorite) { isFavChanged = true; }
                if (filter.Name == filterDto.Name) { isNameChanged = false; }
                if (filter.Type != filterDto.Type && filter.Type != FilterType.Standard) { isSharedChanged = true; }

                //make updates to fields
                filter.Name = filterDto.Name;
                filter.Type = filterDto.Type;
                filter.LastSaved = DateTime.Now.ToUniversalTime();
                filter.IsFavorite = filterDto.IsFavorite;
                filter.Status = filterDto.Status;
                filter.PublishDate = filterDto.PublishDate;
                filter.UnPublishDate = filterDto.UnPublishDate;
                filter.PortfolioId = filterDto.PortfolioId;
                filter.UniverseId = filterDto.UniverseId;
                filter.PeerGroup = filterDto.PeerGroup;
                filter.Region = filterDto.Region;
                filter.Country = filterDto.Country;
                filter.CompanyType = filterDto.CompanyType;
                filter.WeightMatrixId = filterDto.WeightMatrixId;
                filter.ReferenceUniverseId = filterDto.ReferenceUniverseId;
                filter.ComparativeGroup = filterDto.ComparativeGroup;
                filter.CompanyTypePublicOrPrivate = filterDto.CompanyTypePublicOrPrivate;
                filter.ResearchType = filterDto.ResearchType;
                filter.TargetType = filterDto.TargetType;
                filter.ExportType = filterDto.ExportType;
            }

            // if request from CI 
            if (filterDto.Id != null && (currentUser.Id != filter.OwnerUserId) && currentUser.AccountId != filter.AccountId)
            {
                throw new AuthorizationException();
            }

            //if request from AI verify admin claim
            if (string.IsNullOrEmpty(filter.Name))
                throw new FilterValidationException { InternalCode = FilterValidationErrorCodes.NullOrEmptyName };

            if (isNameChanged)
            {
                if (!ValidateFilterPrivateName(filter.Name, currentUser, filterDto.TargetType))
                    throw new FilterValidationException { InternalCode = FilterValidationErrorCodes.DuplicatePrivateName };   
            }

            if (isSharedChanged)
            {
                if (!ValidateFilterSharedName(filter.Name, filterDto.TargetType, filterDto.Type, currentUser))
                    throw new FilterValidationException { InternalCode = FilterValidationErrorCodes.DuplicateSharedName };
            }
                        
            _filtersRepository.SaveFilter(filter);
            _serviceBusPublisher.SendMessage(JsonConvert.SerializeObject(filter), ReplicationUtils.EntityType.Filter, ReplicationUtils.Operation.Create);

            #region custom  ordering 

            var resultSystemAndFav = _userFilterSettingsRepository.ReadAllWhere(x => x.UserId == currentUser.Id && x.AccountId == currentUser.AccountId && x.TargetType == filter.TargetType && x.ScreenRegion == ScreenRegion.SystemAndFavFilters);
            var resultOtherFilters = _userFilterSettingsRepository.ReadAllWhere(x => x.UserId == currentUser.Id && x.AccountId == currentUser.AccountId && x.TargetType == filter.TargetType && x.ScreenRegion == ScreenRegion.OtherFilters);

            UserFilterSettings resultSystemAndFavOrder = null;
            UserFilterSettings resultOtherFiltersOrder = null;

            if (resultSystemAndFav.Any())
            {
                resultSystemAndFavOrder = resultSystemAndFav.FirstOrDefault();
            }

            if (resultOtherFilters.Any())
            {
                resultOtherFiltersOrder = resultOtherFilters.FirstOrDefault();
            }

            //if we add/clone a new filter and we have custom ordering , we should add it to other filters / system and fav ordering of first position

            //if we edit a filter favourite and we have custom ordering , we remove the id from other filters and add it to system and favorite on first position
            //if we edit a filter unfavourite and we have custom ordering , we remove the id from system and favorite and add it to other filters on first position

            //for add filter by default (to other filters) or clone (could be to other filters or system and fav)
            if (filterDto.Id == null || sourceFilterId != null)
            {
                if (resultOtherFiltersOrder != null && filterDto.Type != FilterType.Standard)
                {
                    if (sourceFilterId != null) //clone filter
                    {
                        // try and find the sourceId and insert the new filter id immediatly after it, or at the end if not found
                        if (resultOtherFiltersOrder.FilterIds.Contains(sourceFilterId.Value))
                        {
                            var position = resultOtherFiltersOrder.FilterIds.IndexOf(sourceFilterId.Value);
                            resultOtherFiltersOrder.FilterIds.Insert(position + 1, filter.Id);
                        }
                    }
                    else //new filter
                    {
                        resultOtherFiltersOrder.FilterIds.Add(filter.Id);
                    }
                        
                    _userFilterSettingsRepository.CreateOrUpdate(resultOtherFiltersOrder);
                    _serviceBusPublisher.SendMessage(JsonConvert.SerializeObject(resultOtherFiltersOrder), ReplicationUtils.EntityType.UserFilterSettings, ReplicationUtils.Operation.CreateOrUpdate);
                }
            }
            else //for editing
            {
                if (isFavChanged)
                {
                    if (filter.IsFavorite)
                    {
                        if (resultOtherFiltersOrder != null)
                        {
                            resultOtherFiltersOrder.FilterIds.Remove(filter.Id);
                            _userFilterSettingsRepository.CreateOrUpdate(resultOtherFiltersOrder);
                            _serviceBusPublisher.SendMessage(JsonConvert.SerializeObject(resultOtherFiltersOrder), ReplicationUtils.EntityType.UserFilterSettings, ReplicationUtils.Operation.CreateOrUpdate);
                        }

                        if (resultSystemAndFavOrder != null)
                        {
                            resultSystemAndFavOrder.FilterIds.Add(filter.Id);
                            _userFilterSettingsRepository.CreateOrUpdate(resultSystemAndFavOrder);
                            _serviceBusPublisher.SendMessage(JsonConvert.SerializeObject(resultSystemAndFavOrder), ReplicationUtils.EntityType.UserFilterSettings, ReplicationUtils.Operation.CreateOrUpdate);
                        }
                    }
                    else
                    {
                        if (resultSystemAndFavOrder != null)
                        {
                            resultSystemAndFavOrder.FilterIds.Remove(filter.Id);
                            _userFilterSettingsRepository.CreateOrUpdate(resultSystemAndFavOrder);
                            _serviceBusPublisher.SendMessage(JsonConvert.SerializeObject(resultSystemAndFavOrder), ReplicationUtils.EntityType.UserFilterSettings, ReplicationUtils.Operation.CreateOrUpdate);
                        }

                        if (resultOtherFiltersOrder != null)
                        {
                            resultOtherFiltersOrder.FilterIds.Add(filter.Id);
                            _userFilterSettingsRepository.CreateOrUpdate(resultOtherFiltersOrder);
                            _serviceBusPublisher.SendMessage(JsonConvert.SerializeObject(resultOtherFiltersOrder), ReplicationUtils.EntityType.UserFilterSettings, ReplicationUtils.Operation.CreateOrUpdate);
                        }
                    }
                }
            }

            #endregion


            //if we're making a clone need to copy the filter criterias from the source filter to clone
            //we need to generate new FilterGroup ids for the newly created filter criterias
            if (sourceFilterId != null)
            {
                var sourceFilterCriteria = _filterCriteriaRepository.GetAllFilterCriteriaByFilterId(sourceFilterId.Value);

                var filterCriteriasByGroupId = sourceFilterCriteria.Where(p=>p.FilterGroupId != null).GroupBy(p => p.FilterGroupId).ToDictionary(g => g.Key, g => g.ToList());

                foreach (var key in filterCriteriasByGroupId.Values)
                {
                    var newGuid = Guid.NewGuid();
                    key.ForEach(criteria => 
                    {
                        criteria.FilterGroupId = newGuid;
                        criteria.Id = Guid.NewGuid();
                        criteria.FilterId = filter.Id;
                        _companyScreeningRepository.AddFilterCriteria(criteria);
                        _serviceBusPublisher.SendMessage(JsonConvert.SerializeObject(criteria), ReplicationUtils.EntityType.FilterCriteria, ReplicationUtils.Operation.AddFilterCriteria);
                    });
                }

                //also persist filter criterias with FilterGroupId null
                var nullGroupIdFilterCriterias = sourceFilterCriteria.Where(p => p.FilterGroupId == null);
                nullGroupIdFilterCriterias.ToList().ForEach(criteria => {
                    criteria.FilterGroupId = null;
                    criteria.Id = Guid.NewGuid();
                    criteria.FilterId = filter.Id;
                    _companyScreeningRepository.AddFilterCriteria(criteria);
                    _serviceBusPublisher.SendMessage(JsonConvert.SerializeObject(criteria), ReplicationUtils.EntityType.FilterCriteria, ReplicationUtils.Operation.AddFilterCriteria);
                });
            }

            return filter;
        }

        public void DeleteFullFilter(Guid filterId, string userName)
        {
            Filter filter = _filtersRepository.GetFilterById(filterId);

            if (filter.Type == FilterType.Standard)
                throw new NotAllowedToDeleteFilter();

            User currentUser = _accountsRepository.GetUserByUsername(userName);
            if (currentUser == null)
                throw new UnknownUserException(userName);

            if (filter.Type == FilterType.Private && filter.OwnerUserId != currentUser.Id)
                throw new NotAllowedToDeleteFilter();

            #region custom ordering
            //if we remove a filter and we have custom ordering, remove it from custom filter ordering (UserFilterSettings)
            var resultSystemAndFav = _userFilterSettingsRepository.ReadAllWhere(x => x.UserId == currentUser.Id && x.AccountId == currentUser.AccountId && x.TargetType == filter.TargetType && x.ScreenRegion == ScreenRegion.SystemAndFavFilters);
            if (resultSystemAndFav.Any())
            {
                var result = resultSystemAndFav.FirstOrDefault();
                if (result.FilterIds.Contains(filterId))
                {
                    result.FilterIds.Remove(filterId);

                    _serviceBusPublisher.SendMessage(JsonConvert.SerializeObject(result), ReplicationUtils.EntityType.UserFilterSettings, ReplicationUtils.Operation.Update);
                    _userFilterSettingsRepository.Update(result.Id, result);
                }
            }

            var resultOtherFilters = _userFilterSettingsRepository.ReadAllWhere(x => x.UserId == currentUser.Id && x.AccountId == currentUser.AccountId && x.TargetType == filter.TargetType && x.ScreenRegion == ScreenRegion.OtherFilters);
            if (resultOtherFilters.Any())
            {
                var result = resultOtherFilters.FirstOrDefault();
                if (result.FilterIds.Contains(filterId))
                {
                    result.FilterIds.Remove(filterId);
                    _serviceBusPublisher.SendMessage(JsonConvert.SerializeObject(result), ReplicationUtils.EntityType.UserFilterSettings, ReplicationUtils.Operation.Update);
                    _userFilterSettingsRepository.Update(result.Id, result);
                }
            }
            #endregion

            try
            {
                CompanyScreeningSerilog.Log.UpdateCurrentFilterIfDelete(filterId);
                CompanyScreeningSerilog.Log.UpdateCurrentFilterIfDeleteSuccess(filterId);
                CompanyScreeningSerilog.Log.DeleteResultOutput(filterId);                
                
                _companyScreeningRepository.DeleteResultOutput(filterId);
                _serviceBusPublisher.SendMessage(JsonConvert.SerializeObject(filterId), ReplicationUtils.EntityType.FilterCriteria, ReplicationUtils.Operation.DeleteResultOutput);

                CompanyScreeningSerilog.Log.DeleteResultOutputSuccess(filterId);

                CompanyScreeningSerilog.Log.DeleteAllCriteria(filterId);
                _filterCriteriaRepository.DeleteAllFilterCriteriaByFilterId(filterId);
                _serviceBusPublisher.SendMessage(JsonConvert.SerializeObject(filterId), ReplicationUtils.EntityType.FilterCriteria, ReplicationUtils.Operation.DeleteAllFilterCriteriaByFilterId);

                CompanyScreeningSerilog.Log.DeleteAllCriteriaSuccess(filterId);
                
                CompanyScreeningSerilog.Log.DeleteFilter(filterId);
                _filtersRepository.DeleteFilter(filterId);
                _serviceBusPublisher.SendMessage(JsonConvert.SerializeObject(filterId), ReplicationUtils.EntityType.Filter, ReplicationUtils.Operation.Delete);
                CompanyScreeningSerilog.Log.DeleteFilterSuccess(filterId);
            }

            catch {
                //supress exception
            }
        }

        public void UpdateSelectedCriteriaOrderNumber(Guid filterId, List<Guid> criteriaIds)
        {
            try
            {
                Tuple<Guid, List<Guid>> criteriaOrder = new Tuple<Guid, List<Guid>>(filterId, criteriaIds);
                _serviceBusPublisher.SendMessage(JsonConvert.SerializeObject(criteriaOrder), ReplicationUtils.EntityType.Filter, ReplicationUtils.Operation.UpdateSelectedCriteriaOrderNumber);

                _companyScreeningRepository.UpdateSelectedCriteriaOrderNumber(filterId, criteriaIds);
            }
            catch (Exception ex)
            {
                throw;
            }
        }


        public void SaveUserCustomFilterOrder(Guid userId, Guid? accountId, TargetType targetType, ScreenRegion screenRegion, List<Guid> filterIds)
        {
            UserFilterSettings setting;

            var settings = _userFilterSettingsRepository.ReadAllWhere(x => x.UserId == userId && x.AccountId == accountId && x.TargetType == targetType && x.ScreenRegion == screenRegion);

            if (settings.Any())
            {
                setting = settings.FirstOrDefault();
                setting.FilterIds = filterIds;
            }
            else
            {
                setting = new UserFilterSettings()
                {
                    UserId = userId,
                    AccountId = accountId,
                    TargetType = targetType,
                    ScreenRegion = screenRegion,
                    FilterIds = filterIds
                };
            }
            _userFilterSettingsRepository.CreateOrUpdate(setting);
            _serviceBusPublisher.SendMessage(JsonConvert.SerializeObject(setting), ReplicationUtils.EntityType.UserFilterSettings, ReplicationUtils.Operation.CreateOrUpdate);

        }


        #region filter validation
        private bool ValidateFilterPrivateName(string filterName, User currentUser, TargetType targetType)
        {
            var count = _filtersRepository.GetFiltersCount(new List<Guid>() { currentUser.Id }, currentUser.AccountId, filterName, targetType, null, 0, 1);
            return count == 0;
        }

        private bool ValidateFilterSharedName(string filterName, TargetType targetType, FilterType filterType, User currentUser)
        {
            Guid currentUserId = currentUser.Id;
            if (filterType == FilterType.Shared && currentUser.AccountId != null)
            {
                var accountId = currentUser.AccountId.Value;
                var usersCount = this._accountsRepository.GetUsersByAccountIdTotalCount(Status.Active, accountId);
                int pageSize = 100;

                //set max iteration if is GetUsers doesnt play.
                int pagesNo = usersCount / pageSize + 1;
                for (int i = 0; i < pagesNo; i++)
                {
                    ListOptions listOption = new ListOptions();
                    listOption.Take = pageSize;
                    var accountsUsers = _accountsRepository.GetUsers(new List<Guid>() { currentUser.AccountId.Value }, Status.Active, "", listOption);
                    if (accountsUsers == null || accountsUsers.Count == 0) { break; }


                    var ids = accountsUsers.Where(x => x.Id != currentUserId).Select(x => x.Id);

                    var count = _filtersRepository.GetFiltersCount(ids.ToList(), currentUser.AccountId, filterName, targetType, FilterType.Shared, 0, 1);

                    if (count > 0) { return false; }
                }
            }

            return true;
        }

        #endregion

    }
}
